fix(cast): decode replay blocks with AnyNetwork - #16459
Merged
Merged
Conversation
`cast run` built its provider from `FEN::Network`, which for every chain
outside Optimism, Tempo and Monad is the strict Ethereum network. A block
containing a transaction type that envelope cannot decode failed to
deserialize as a whole:
Error: deserialization error: data did not match any variant of
untagged enum BlockTransactions
Arbitrum puts its internal transaction (type `0x6a`) at index 0 of every
block, so no Arbitrum transaction has ever been replayable. Celo (`0x7b`)
and OP-stack forks Foundry does not route to the Optimism network, such
as Mantle and Berachain (`0x7e`), fail the same way. `cast tx` and
`cast block --full` already use `AnyNetwork` and were unaffected.
RPC now uses `AnyNetwork` and transactions convert through
`FromAnyRpcTransaction`, which execution already relies on in the fork
backend. Transactions are classified as system transactions before being
decoded, since a chain's reserved envelopes are exactly the ones this
build may not decode, and Monad keeps a typed provider for its block
context.
`FromAnyRpcTransaction for OpTx` left `enveloped_tx` empty, which op-revm
rejects for non-deposit transactions because the L1 data fee is charged
off those bytes. It now carries the 2718 encoding, which keeps Optimism
and Base exact through the new path.
Verified against live nodes: Arbitrum transactions replay and match
receipt gas exactly once `gasUsedForL1` is subtracted, and Ethereum,
Optimism and Base still match receipt gas exactly.
mattsse
requested review from
0xrusowsky,
DaniPopes,
grandizzy and
mablr
as code owners
August 29, 2026 02:09
Contributor
✅ Changelog foundThe deterministic check will validate the changed entry. |
figtracer
previously approved these changes
Aug 29, 2026
stevencartavia
approved these changes
Aug 29, 2026
This was referenced Aug 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
cast runbuilt its provider fromFEN::Network, which outside Optimism, Tempo and Monad is the strict Ethereum network. One transaction that envelope cannot decode fails the whole block:Arbitrum puts its internal transaction (type
0x6a) at index 0 of every block, so no Arbitrum transaction has ever been replayable —--quickincluded, and as far back as I looked. Celo (0x7b) and the OP-stack forks Foundry does not route to the Optimism network, such as Mantle and Berachain (0x7e), fail the same way.cast txandcast block --fullwere never affected because they already useAnyNetwork.RPC now decodes with
AnyNetworkand transactions convert throughFromAnyRpcTransaction, which the fork backend already relies on for exactly this reason. Two details fall out of that. Transactions are classified as system transactions before being decoded, since the envelopes a chain reserves for itself are precisely the ones this build may not decode. And Monad keeps a typed provider for its block context, which is defined overFEN::Network.Moving Optimism onto the same path surfaced a second bug:
FromAnyRpcTransaction for OpTxleftenveloped_txempty, and op-revm rejects a non-deposit transaction without it, since the L1 data fee is charged off those bytes. It now carries the 2718 encoding.Verified against live nodes. Arbitrum transactions replay and match receipt gas exactly once
gasUsedForL1is subtracted — 216899 on-chain, 273 of it L1, 216626 locally. Ethereum, Optimism and Base still match receipt gas exactly.Arbitrum needs #16457 as well to replay end to end; without it the block decodes and then stops on
MissingParentBeaconBlockRoot. The two are independent and touch different hunks. Celo's0x7bfee-currency transactions still cannot be converted — that needs Celo-specific handling and is out of scope here, though Celo's standard transactions now work.This PR was written by Claude Code, including the investigation behind it and this description. Verified against live nodes for each chain named above.